home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / c / gcc261ud-c.lha / gnu / ManualBrowser / main.c < prev    next >
C/C++ Source or Header  |  1994-09-06  |  16KB  |  606 lines

  1. /************************************************************************/
  2. /*                                    */
  3. /*  Copyright (C) 1994  Christian Stieber                */
  4. /*                                    */
  5. /* This program is free software; you can redistribute it and/or modify    */
  6. /* it under the terms of the GNU General Public License as published by    */
  7. /* the Free Software Foundation; either version 2 of the License, or    */
  8. /* (at your option) any later version.                    */
  9. /*                                    */
  10. /* This program is distributed in the hope that it will be useful,    */
  11. /* but WITHOUT ANY WARRANTY; without even the implied warranty of    */
  12. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
  13. /* GNU General Public License for more details.                */
  14. /*                                    */
  15. /* You should have received a copy of the GNU General Public License    */
  16. /* along with this program; if not, write to the Free Software        */
  17. /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.        */
  18. /*                                    */
  19. /************************************************************************/
  20. /*                                    */
  21. /* Author address:                            */
  22. /*   Christian Stieber                            */
  23. /*   Konradstraße 41                            */
  24. /*   D-85055 Ingolstadt                            */
  25. /*   (Germany)                                */
  26. /*   Phone: 0841-59896                            */
  27. /*                                    */
  28. /************************************************************************/
  29.  
  30. #ifndef V39
  31.    #define CreatePool LibCreatePool
  32.    #define DeletePool LibDeletePool
  33.    #define AllocPooled LibAllocPooled
  34.    #define FreePooled LibFreePooled
  35. #endif
  36.  
  37. #ifndef DOS_DOSEXTENS_H
  38. #include <dos/dosextens.h>
  39. #endif
  40.  
  41. #ifndef DOS_EXALL_H
  42. #include <dos/exall.h>
  43. #endif
  44.  
  45. #ifndef INTUITION_INTUITION_H
  46. #include <intuition/intuition.h>
  47. #endif
  48.  
  49. #ifndef LIBRARIES_AMIGAGUIDE_H
  50. #include <libraries/amigaguide.h>
  51. #endif
  52.  
  53. #ifndef WORKBENCH_STARTUP_H
  54. #include <workbench/startup.h>
  55. #endif
  56.  
  57. #ifndef WORKBENCH_WORKBENCH_H
  58. #include <workbench/workbench.h>
  59. #endif
  60.  
  61. #ifndef __GNUC__
  62.    #ifndef CLIB_EXEC_PROTOS_H
  63.    #include <clib/exec_protos.h>
  64.    #endif
  65.  
  66.    #ifndef CLIB_DOS_PROTOS_H
  67.    #include <clib/dos_protos.h>
  68.    #endif
  69.  
  70.    #ifndef CLIB_UTILITY_PROTOS_H
  71.    #include <clib/utility_protos.h>
  72.    #endif
  73.  
  74.    #ifndef CLIB_INTUITION_PROTOS_H
  75.    #include <clib/intuition_protos.h>
  76.    #endif
  77.  
  78.    #ifndef CLIB_ICON_PROTOS_H
  79.    #include <clib/icon_protos.h>
  80.    #endif
  81.  
  82.    #ifndef CLIB_AMIGAGUIDE_PROTOS_H
  83.    #include <clib/amigaguide_protos.h>
  84.    #endif
  85.  
  86.    #include <pragmas/exec_pragmas.h>
  87.    #include <pragmas/dos_pragmas.h>
  88.    #include <pragmas/intuition_pragmas.h>
  89.    #include <pragmas/utility_pragmas.h>
  90.    #include <pragmas/icon_pragmas.h>
  91.    #include <pragmas/amigaguide_pragmas.h>
  92. #endif
  93.  
  94. #include <string.h>
  95.  
  96. #include "Globals.h"
  97.  
  98. /***********************************************/
  99.  
  100. struct DosLibrary *DOSBase;
  101. struct IntuitionBase *IntuitionBase;
  102. struct Library *AmigaGuideBase;
  103. struct Library *UtilityBase;
  104.  
  105. /***********************************************/
  106.  
  107. #ifdef __GNUC__
  108.  
  109. #include "Inlines.h"
  110.  
  111. #ifndef V39
  112.    APTR AllocPooled(APTR, ULONG);
  113.    void FreePooled(APTR, APTR, ULONG);
  114.    APTR CreatePool(ULONG, ULONG, ULONG);
  115.    void DeletePool(APTR);
  116. #endif
  117.  
  118. #endif   /* __GNUC__ */
  119.  
  120. /***********************************************/
  121.  
  122. #define CONFIGFILE    "ManualBrowser.config"
  123.  
  124. /***********************************************/
  125.  
  126. char Version[]="$VER: ManualBrowser " PROGVERSION " (" PROGDATE ")"
  127. #ifdef V39
  128. "(V39) "
  129. #endif
  130. "(" CPU ") "
  131. "© 1994 Christian Stieber";
  132.  
  133. /***********************************************/
  134.  
  135. #define BASENAME   "ManBrowser"
  136. #define PUDDLESIZE (20*1024)
  137.  
  138. /***********************************************/
  139.  
  140. void *MemoryPool;
  141. struct ActionNode *ActionList;
  142. BPTR ManDir;
  143. long LineLength=70;
  144. char DatabaseName[64];
  145.  
  146. /***********************************************/
  147.  
  148. static AMIGAGUIDEHOST AmigaGuideHostHandle;
  149. static AMIGAGUIDECONTEXT AmigaGuideHandle;
  150.  
  151. static char Filename[64];
  152.  
  153. static BPTR FileHandle;
  154.  
  155. static struct WBStartup *WBStartupMessage;
  156.  
  157. static struct EasyStruct EasyStruct=
  158.    {
  159.       5*4,
  160.       0,
  161.       "Manual browser " PROGVERSION " error",
  162.       NULL,
  163.       NULL
  164.    };
  165.  
  166. /***********************************************/
  167.  
  168. #ifdef __GNUC__
  169. static void MyExit(int) __attribute__((noreturn));
  170. #endif
  171.  
  172. static void MyExit(int RC)
  173.  
  174. {
  175.    if (WBStartupMessage)
  176.       {
  177.          Forbid();
  178.          ReplyMsg((struct Message *)WBStartupMessage);
  179.       }
  180.    exit(RC);
  181. }
  182.  
  183. /***********************************************/
  184.  
  185. static int DisplayError(char *Action, char *Format,...)
  186.  
  187. {
  188.    if (WBStartupMessage)
  189.       {
  190.          EasyStruct.es_TextFormat=Format;
  191.          EasyStruct.es_GadgetFormat=Action;
  192.          return EasyRequestArgs(NULL,&EasyStruct,NULL,(&Format)+1);
  193.       }
  194.    else
  195.       {
  196.          VPrintf(Format,(&Format)+1);
  197.          PutStr("\n");
  198.          return 0;
  199.       }
  200.    /* not reached */
  201. }
  202.  
  203. /***********************************************/
  204.  
  205. static int DisplayDosError(char *Action, char *Filename)
  206.  
  207. {
  208.    if (WBStartupMessage)
  209.       {
  210.          char Buffer[256];
  211.          char *t;
  212.  
  213.          t=Buffer;
  214.          Fault(IoErr(),Filename,t,sizeof(Buffer));
  215.          EasyStruct.es_TextFormat="%s";
  216.          EasyStruct.es_GadgetFormat=Action;
  217.          return EasyRequestArgs(NULL,&EasyStruct,NULL,&t);
  218.       }
  219.    else
  220.       {
  221.          PrintFault(IoErr(),Filename);
  222.          return 0;
  223.       }
  224.    /* not reached */
  225. }
  226.  
  227. /***********************************************/
  228.  
  229. #ifdef __GNUC__
  230. static void CloseAll(int) __attribute__((noreturn));
  231. #endif
  232.  
  233. static void CloseAll(int RC)
  234.  
  235. {
  236.    if (AmigaGuideHandle) CloseAmigaGuide(AmigaGuideHandle);
  237.    if (AmigaGuideHostHandle)
  238.       {
  239.          while (RemoveAmigaGuideHostA(AmigaGuideHostHandle,NULL))
  240.             {
  241.                Delay(TICKS_PER_SECOND);
  242.             }
  243.       }
  244.    if (FileHandle)
  245.       {
  246.          DeleteFile(Filename);
  247.       }
  248.    if (ManDir) UnLock(ManDir);
  249.    if (MemoryPool) DeletePool(MemoryPool);
  250.    CloseLibrary(AmigaGuideBase);
  251.    CloseLibrary(UtilityBase);
  252.    CloseLibrary((struct Library *)IntuitionBase);
  253.    CloseLibrary((struct Library *)DOSBase);
  254.    MyExit(RC);
  255. }
  256.  
  257. /***********************************************/
  258.  
  259. static void InitThings(void)
  260.  
  261. {
  262.    struct Process *MyProcess;
  263.  
  264.    MyProcess=(struct Process *)FindTask(NULL);
  265.    if (MyProcess->pr_CLI)
  266.       {
  267.          WBStartupMessage=NULL;
  268.       }
  269.    else
  270.       {
  271.          do
  272.             {
  273.                WaitPort(&MyProcess->pr_MsgPort);
  274.             }
  275.          while (!(WBStartupMessage=(struct WBStartup *)GetMsg(&MyProcess->pr_MsgPort)));
  276.       }
  277.  
  278. #ifdef V39
  279.    if (!(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",39)))
  280. #else
  281.    if (!(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37)))
  282. #endif
  283.       {
  284.          MyExit(100);
  285.       }
  286.  
  287.    if (!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37)))
  288.       {
  289.          CloseLibrary((struct Library *)DOSBase);
  290.          MyExit(100);
  291.       }
  292.  
  293.    if (!(UtilityBase=OpenLibrary("utility.library",37)))
  294.       {
  295.          DisplayError("Quit","Unable to open utility.library V37");
  296.          CloseAll(RETURN_FAIL);
  297.       }
  298.  
  299.    if (!(AmigaGuideBase=OpenLibrary("amigaguide.library",34)))
  300.       {
  301.          DisplayError("Quit","Unable to open amigaguide.library V34");
  302.          CloseAll(RETURN_FAIL);
  303.       }
  304.  
  305.    if (!(MemoryPool=CreatePool(0,PUDDLESIZE,PUDDLESIZE)))
  306.       {
  307.          DisplayError("Quit","Unable to create memory pool");
  308.          CloseAll(RETURN_FAIL);
  309.       }
  310. }
  311.  
  312. /***********************************************/
  313.  
  314. static void AddDatabase(void)
  315.  
  316. {
  317.    #ifdef __GNUC__
  318.    static struct Hook AmigaGuideHook=
  319.       {
  320.          {NULL,NULL},
  321.          HookEntryA1,
  322.          AmigaGuideHostDispatcher,
  323.          NULL
  324.       };
  325.    #else
  326.    static struct Hook AmigaGuideHook=
  327.       {
  328.          {NULL,NULL},
  329.          AmigaGuideHostDispatcher,
  330.          NULL,
  331.          NULL
  332.       };
  333.    #endif
  334.  
  335.    char *t;
  336.  
  337.    Sprintf(DatabaseName,BASENAME ".%lx",FindTask(NULL));
  338.    Sprintf(Filename,"t:%s.guide",DatabaseName);
  339.  
  340.    if (!(FileHandle=Open(Filename,MODE_NEWFILE)))
  341.       {
  342.          DisplayDosError("Quit",Filename);
  343.          CloseAll(RETURN_ERROR);
  344.       }
  345.    t=DatabaseName;
  346.    if (VFPrintf(FileHandle,"@database %s.guide\n"
  347.                            "@node EnItSiRhC\n"
  348.                            "@endnode\n",&t)==-1)
  349.       {
  350.          DisplayDosError("Quit",Filename);
  351.          Close(FileHandle);
  352.          CloseAll(RETURN_ERROR);
  353.       }
  354.    Close(FileHandle);
  355.  
  356.    if (!(AmigaGuideHostHandle=AddAmigaGuideHostA(&AmigaGuideHook,DatabaseName,NULL)))
  357.       {
  358.          DisplayError("Quit","Unable to add dynamic amiga guide host");
  359.          CloseAll(RETURN_FAIL);
  360.       }
  361. }
  362.  
  363. /***********************************************/
  364.  
  365. static void OpenDatabase(void)
  366.  
  367. {
  368.    struct NewAmigaGuide NewAmigaGuide;
  369.  
  370.    NewAmigaGuide.nag_Lock=NULL;
  371.    NewAmigaGuide.nag_Name=Filename;
  372.    NewAmigaGuide.nag_Screen=NULL;
  373.    NewAmigaGuide.nag_PubScreen=NULL;
  374.    NewAmigaGuide.nag_HostPort=NULL;
  375.    NewAmigaGuide.nag_ClientPort=BASENAME;
  376.    NewAmigaGuide.nag_BaseName=BASENAME;
  377.    NewAmigaGuide.nag_Flags=HTF_NOACTIVATE;
  378.    NewAmigaGuide.nag_Context=NULL;
  379.    NewAmigaGuide.nag_Node=NULL;
  380.    NewAmigaGuide.nag_Line=0;
  381.    NewAmigaGuide.nag_Extens=NULL;
  382.    NewAmigaGuide.nag_Client=NULL;
  383.  
  384.    if (!(AmigaGuideHandle=OpenAmigaGuideA(&NewAmigaGuide,NULL)))
  385.       {
  386.          DisplayError("Quit","Unable to open amiga guide database");
  387.          CloseAll(RETURN_FAIL);
  388.       }
  389. }
  390.  
  391. /***********************************************/
  392.  
  393. #ifdef __GNUC__
  394. #define ICONBASE IconBase,
  395. #else
  396. #define ICONBASE
  397. #endif
  398.  
  399. static void GetParams(void)
  400.  
  401. {
  402.    if (WBStartupMessage)
  403.       {
  404.          struct Library *IconBase;
  405.  
  406.          if ((IconBase=OpenLibrary("icon.library",33)))
  407.             {
  408.                if (WBStartupMessage->sm_NumArgs)
  409.                   {
  410.                      BPTR OldCurrDir;
  411.                      struct DiskObject *DiskObject;
  412.                      OldCurrDir=CurrentDir(WBStartupMessage->sm_ArgList[0].wa_Lock);
  413.                      if ((DiskObject=GetDiskObject(ICONBASE WBStartupMessage->sm_ArgList[0].wa_Name)))
  414.                         {
  415.                            char *ManPath;
  416.                            if (!((ManPath=FindToolType(ICONBASE (UBYTE **)DiskObject->do_ToolTypes,"MANUALDIR")) ||
  417.                                  (ManPath=FindToolType(ICONBASE (UBYTE **)DiskObject->do_ToolTypes,"MANDIR")) ||
  418.                                  (ManPath=FindToolType(ICONBASE (UBYTE **)DiskObject->do_ToolTypes,"DIR"))))
  419.                               {
  420.                                  ManPath="man:";
  421.                               }
  422.                            if (!(ManDir=Lock(ManPath,SHARED_LOCK)))
  423.                               {
  424.                                  DisplayDosError("Quit",ManPath);
  425.                               }
  426.                            FreeDiskObject(ICONBASE DiskObject);
  427.                         }
  428.                      CurrentDir(OldCurrDir);
  429.                   }
  430.                CloseLibrary(IconBase);
  431.             }
  432.       }
  433.    else
  434.       {
  435.          struct
  436.             {
  437.                char *ManualDir;
  438.             } Arguments;
  439.  
  440.          struct RDArgs *RDArgs;
  441.  
  442.          Arguments.ManualDir="man:";
  443.          if (!(RDArgs=ReadArgs("MANUALDIR=MANDIR=DIR",(long *)&Arguments,NULL)))
  444.             {
  445.                PrintFault(IoErr(),NULL);
  446.                CloseAll(RETURN_FAIL);
  447.             }
  448.          if (!(ManDir=Lock(Arguments.ManualDir,SHARED_LOCK)))
  449.             {
  450.                DisplayDosError("Quit",Arguments.ManualDir);
  451.             }
  452.          FreeArgs(RDArgs);
  453.       }
  454.    if (!ManDir)
  455.       {
  456.          CloseAll(RETURN_FAIL);
  457.       }
  458. }
  459.  
  460. /***********************************************/
  461.  
  462. static void ReadConfigFile(BPTR ConfigFile, char *Filename)
  463.  
  464. {
  465.    BPTR OldInput;
  466.  
  467.    OldInput=SelectInput(ConfigFile);
  468.    while (TRUE)
  469.       {
  470.          struct
  471.             {
  472.                char *Pattern;
  473.                char *Action;
  474.             } CurrentLine;
  475.          struct RDArgs *LineArgs;
  476.  
  477.          while (TRUE)
  478.             {
  479.                int Character;
  480.  
  481.                Character=FGetC(ConfigFile);
  482.                if (Character!='\n' && Character!=' ' && Character!='\t')
  483.                   {
  484.                      if (Character==-1)
  485.                         {
  486.                            if (IoErr())
  487.                               {
  488.                                  DisplayDosError("Quit",Filename);
  489.                                  Close(ConfigFile);
  490.                                  CloseAll(RETURN_ERROR);
  491.                               }
  492.                            goto Done;
  493.                         }
  494.                      UnGetC(ConfigFile,Character);
  495.                      break;
  496.                   }
  497.             }
  498.          CurrentLine.Pattern=NULL;
  499.          CurrentLine.Action=NULL;
  500.          if ((LineArgs=ReadArgs("P/A,A/A/F",(long *)&CurrentLine,NULL)))
  501.             {
  502.                struct ActionNode *ActionNode;
  503.                int AllocSize, PatternSize;
  504.                PatternSize=2*strlen(CurrentLine.Pattern);
  505.                AllocSize=sizeof(struct ActionNode)+strlen(CurrentLine.Action)+PatternSize;
  506.                if ((ActionNode=AllocPooled(MemoryPool,AllocSize)))
  507.                   {
  508.                      ActionNode->Pattern=Stpcpy(ActionNode->Action,CurrentLine.Action)+1;
  509.                      if (ParsePatternNoCase(CurrentLine.Pattern,ActionNode->Pattern,PatternSize)!=-1)
  510.                         {
  511.                            ActionNode->Next=ActionList;
  512.                            ActionList=ActionNode;
  513.                         }
  514.                      else
  515.                         {
  516.                            FreePooled(MemoryPool,ActionNode,AllocSize);
  517.                            if (!DisplayError("Ignore|Quit","Error in pattern: %s",CurrentLine.Pattern))
  518.                               {
  519.                                  ActionNode=NULL;
  520.                               }
  521.                         }
  522.                   }
  523.                else
  524.                   {
  525.                      DisplayDosError("Quit",NULL);
  526.                   }
  527.                FreeArgs(LineArgs);
  528.                if (!ActionNode)
  529.                   {
  530.                      Close(ConfigFile);
  531.                      CloseAll(RETURN_ERROR);
  532.                   }
  533.             }
  534.          else
  535.             {
  536.                if (!DisplayDosError("Ignore line|Quit",NULL))
  537.                   {
  538.                      Close(ConfigFile);
  539.                      CloseAll(RETURN_ERROR);
  540.                   }
  541.             }
  542.       }
  543.    /* Not reached */
  544.  
  545. Done:
  546.    SelectInput(OldInput);
  547. }
  548.  
  549. /***********************************************/
  550.  
  551. #define CONFIGPATHLEN 4096
  552.  
  553. static void ReadConfig(void)
  554.  
  555. {
  556.    static char *ConfigFile[]=
  557.       {
  558.          "PROGDIR:" CONFIGFILE,
  559.          "S:" CONFIGFILE,
  560.          "ENV:" CONFIGFILE
  561.       };
  562.  
  563.    int i;
  564.  
  565.    for (i=0; i<3; i++)
  566.       {
  567.          BPTR FileHandle;
  568.          if ((FileHandle=Open(ConfigFile[i],MODE_OLDFILE)))
  569.             {
  570.                char *Filename, *t;
  571.                Filename=ConfigFile[i];
  572.                if ((t=AllocPooled(MemoryPool,CONFIGPATHLEN)))
  573.                   {
  574.                      if (NameFromFH(FileHandle,t,CONFIGPATHLEN))
  575.                         {
  576.                            Filename=t;
  577.                         }
  578.                   }
  579.                ReadConfigFile(FileHandle,Filename);
  580.                if (t)
  581.                   {
  582.                      FreePooled(MemoryPool,t,CONFIGPATHLEN);
  583.                   }
  584.                Close(FileHandle);
  585.             }
  586.       }
  587. }
  588.  
  589. #undef CONFIGPATHLEN
  590.  
  591. /***********************************************/
  592.  
  593. void Main(void);
  594.  
  595. void Main(void)
  596.  
  597. {
  598.    InitThings();
  599.    GetParams();
  600.    ReadConfig();
  601.    AddDatabase();
  602.    OpenDatabase();
  603.    CloseAll(RETURN_OK);
  604.    /* Not reached */
  605. }
  606.